<script setup lang="ts">
    import {nextTick, onMounted, reactive, ref} from 'vue'
    import { allRoleAPI, addOrUpdateRoleAPI, allMenuListAPI, setPermisstionAPI, removeRoleAPI} from '@/network/acl/role';
    import type { RoleResponseData, Records, RoleData, MenuResponseData, MenuList } from '@/network/acl/role/type';
    // 当前页面
    const pageNO = ref<number>(1)
    // 每一页展示数据条数
    const limit = ref<number>(5)
    const total = ref<number>(0)
    // 搜索关键字
    const keyword = ref<string>('')

    const roleArr = ref<Records>([])

   async function getAllRole(page = 1) {
        pageNO.value = page
        const res: RoleResponseData = await allRoleAPI(pageNO.value, limit.value, keyword.value)
        // console.log(res);
        if (res.code === 200) {
            roleArr.value = res.data.records
            total.value  = res.data.total 
        }
    }

    onMounted(() => {
        getAllRole()
    })

    // 切换每页多少条的方法
    function sizeChange() {
        getAllRole()
    }

    // 搜索
    function search() {
        // 根据关键字，获取对应的数据
        getAllRole()
        keyword.value = ''
    }

    import { storeToRefs } from 'pinia';
    import { useLayoutSettingStore } from '@/store/modules/setting';
    import { ElMessage } from 'element-plus';
    // 改变仓库里的refresh属性，main展示区会监测refresh变化，然后销毁重建main
    const {refresh} = storeToRefs(useLayoutSettingStore())
    // 重置
    function reset() {
        refresh.value = !refresh.value
    }

    // 添加与修改
    // 收集新增数据
    let roleParams = reactive<RoleData>({
        roleName: ''
    })

    const dialogVisible = ref<boolean>(false)

    // 收集表单项的实例
    const formItem = ref()
    function addRole() {
        // 先清空数据
        // 如果先修改，会遗留id 再次添加时，需要删除，避免影响后续判断
        delete roleParams.id
        Object.assign(roleParams, {
            roleName: ''
        })
        dialogVisible.value = true
        nextTick(() => {
            // console.log(formItem.value);
            // 清空验证信息
            formItem.value.clearValidate()
        })
    }

    function updateRole(row: RoleData) {
        // 此处赋值需深拷贝，不然两个对象用的同一个地址，修改一个，另一个也会变化
        Object.assign(roleParams, JSON.parse(JSON.stringify(row)))
        dialogVisible.value = true
        nextTick(() => {
            // console.log(formItem.value);
            // 清空验证信息
            formItem.value.clearValidate()
        })
    }

    

    // 保存
    // 获取表单实例
    const form = ref()
    async function save() {
        // 表单校验全部通过再请求
        await form.value.validate()
       const res: any = await addOrUpdateRoleAPI(roleParams)
       console.log(res);
       if (res.code === 200) {
           ElMessage({
                type: 'success',
                message: roleParams.id ? '修改职位成功' : '添加职位成功'
           })
           getAllRole(roleParams.id ? pageNO.value : 1)
           dialogVisible.value = false         
       } else {
            ElMessage({
                type: 'error',
                message: roleParams.id ? '修改职位失败' : '添加职位失败'
            })        
       }
    }

    // 表单校验
    const validatorRoleName = (rule: any, value: any, callBack: any) => {
        if (value.trim().length >= 2) {
            callBack()
        } else {
            callBack(new Error('职位名称必须大于等于两位'))
        }
    }
    const rules = {
       roleName: [
            {required: true, trigger: 'blur', validator: validatorRoleName}
        ]
    }

    // 分配权限
    const drawer = ref<boolean>(false)
    const menuArr = ref<MenuList>([])
    // 树形控件标签和子节点
     const defaultProps = {
        children: 'children',
        label: 'name',
    }
    // 分配权限的按钮
   async function setPermissions(row: RoleData) {
    // 分配权限要用
    Object.assign(roleParams, row)
        drawer.value = true
        // 根据职位id获取菜单权限的数据
        const res: MenuResponseData = await allMenuListAPI(row.id)
        console.log(res);
        if (res.code === 200) {
            menuArr.value = res.data
            // 过滤出四级id
            filterSelectArr(menuArr.value)
        }
    }
    // 存储勾选的节点的id(注意是四级的id)
    const selectIdArr = ref<number[]>([])
    function filterSelectArr(menuArr: MenuList) {
        menuArr.forEach(item => {
            if (item.select && item.level === 4) {
                selectIdArr.value.push(item.id)
            }
            if (item.children && item.children.length !== 0) {
                // 递归
                filterSelectArr(item.children)
            }
        })
    }

    const tree = ref<any>()

    // 分配权限的函数，确定按钮
   async function handler() {
        // 职位的id
        const roleId = roleParams.id
        // 选中节点的id
        const arr = tree.value.getCheckedKeys()
        // 半选
        const arr2 = tree.value.getHalfCheckedKeys()
        const permissionId = arr.concat(arr2)
        console.log(permissionId);
        const res = await setPermisstionAPI(roleId, permissionId)
        console.log(res);
        if (res.code === 200) {
            ElMessage({
                type: 'success',
                message: '添加权限成功'
            })
            drawer.value = false
            // 页面刷新，展现出该有的权限
            window.location.reload()
        }
    }

    // 删除职位
   async function deleteRole(row: RoleData) {
        const res = await removeRoleAPI(row.id)
        console.log(res);
        if (res.code === 200) {
            ElMessage({
                type: 'success',
                message: '删除职位成功'
            })
            getAllRole(roleArr.value.length > 1 ? pageNO.value : pageNO.value - 1)
        } else {
            ElMessage({
                type: 'error',
                message: `删除职位失败 ${res.data}`
            })
        }
    }


   

</script>


<template>
    <div>
        <el-card>
            <el-form :inline="true" class="form">
                <el-form-item label="职位搜索">
                    <el-input v-model="keyword" placeholder="请输入职位关键字"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-button @click="search" :disabled="!keyword" type="primary">搜索</el-button>
                    <el-button @click="reset" type="primary">重置</el-button>
                </el-form-item>
            </el-form>    
        </el-card>
        <el-card style="margin: 10px 0;">
            <el-button v-has="'btn.Role.add'" @click="addRole" type="primary">添加职位</el-button>
            <el-table style="margin: 10px 0;" border :data="roleArr">
                <el-table-column align="center" label="#" type="index"></el-table-column>
                <el-table-column prop="id" align="center" label="ID"></el-table-column>
                <el-table-column prop="roleName" show-overflow-tooltip align="center" label="职位名称"></el-table-column>
                <el-table-column prop="createTime" show-overflow-tooltip align="center" label="创建时间"></el-table-column>
                <el-table-column prop="updateTime" show-overflow-tooltip align="center" label="更新时间"></el-table-column>
                <el-table-column align="center" label="操作" width="300px">
                    <template #="{row, $index}">
                        <el-button v-has="'btn.Role.assgin'" @click="setPermissions(row)" size="small" type="primary" icon="User">分配权限</el-button>
                        <el-button v-has="'btn.Role.update'" @click="updateRole(row)" size="small" type="primary" icon="Edit">编辑</el-button>
                        <el-popconfirm width="220px" @confirm="deleteRole(row)" :title="`确定要删除${row.roleName}吗？`">
                            <template #reference>
                                <el-button v-has="'btn.Role.remove'" size="small" type="danger" icon="delete">删除</el-button>
                            </template>
                        </el-popconfirm>
                    </template>
                </el-table-column>
            </el-table>
            <el-pagination
            v-model:current-page="pageNO"
            v-model:page-size="limit"
            :page-sizes="[3, 5, 7, 9]"
            :background="true"
            layout="prev, pager, next, jumper, ->, total, sizes,"
            :total="total"
            @current-change="getAllRole"
            @size-change="sizeChange"
            />
        </el-card>
        <!-- 添加与更新对话框 -->
         <el-dialog v-model="dialogVisible" :title="roleParams.id ? '修改职位' : '添加职位'">
            <el-form ref="form" :model="roleParams" :rules="rules">
                <el-form-item ref="formItem" prop="roleName" label="职位名称">
                    <el-input v-model="roleParams.roleName" placeholder="请输入职位名称"></el-input>
                </el-form-item>
            </el-form>
            <template #footer>
                <el-button @click="dialogVisible = false">取消</el-button>
                <el-button @click="save" type="primary">确定</el-button>
            </template>
         </el-dialog>
         <!-- 抽屉组件：分配职位的菜单权限与按钮的权限 -->
         <el-drawer v-model="drawer" title="分配菜单与按钮的权限">
            <!--
                1. default-expand-all	是否默认展开所有节点
                2. default-checked-keys	默认勾选的节点的 key 的数组
              -->
            <el-tree
                ref="tree"
                style="max-width: 600px"
                :data="menuArr"
                show-checkbox
                node-key="id"
                default-expand-all
                :default-checked-keys="selectIdArr"
                :props="defaultProps"/>
            <template #footer>
                <div style="flex: auto">
                    <el-button @click="drawer = false">取消</el-button>
                    <el-button @click="handler" type="primary">确定</el-button>
                </div>
            </template>
        </el-drawer>
    </div>
</template>


<style scoped lang='scss'>
    .form{
        display: flex;
        justify-content: space-between;
        align-items: center;
    }
</style>